<?php

namespace co2\dev\v0_0_0;

class PDO

{
	protected
		$PDO,
		$adapters=array()
		;
		
	public function
	__construct
	(
		$adapter,
		$username=null,
		$password=null,
		\stdClass $options=null
	)
	{
	  $this->adapters=\PDO::getAvailableDrivers();
	
		if(!in_array($adapter,$this->adapters))
		throw new Exception('PDO driver unavailable');
		
		$dsn="$adapter:";
		
		if($adapter=='sqlite')
		$dsn.=$username;
		else
		{
		  if(is_object($options))
		  foreach(array('dbname','host','port','charset') as $_)
		  if(isset($options->$_))
		  $dsn.="$_={$options->$_};"; 
		}

		try
		{
		  $options=$adapter=='sqlite'?null :array
		  (
			  1002 => "SET NAMES $charset"
		  ); 
		
			$this->PDO=new \PDO($dsn,$username,$password,$options);
		
			$this->PDO->setAttribute(\PDO::ATTR_ERRMODE,\PDO::ERRMODE_EXCEPTION);
		
		  if($adapter!='sqlite')
			$this->PDO->exec("SET CHARACTER SET $charset");
		}
		catch(\PDOException $e)
		{
			new Exception\rethrow($e);
		}
	}
	
	public function
	__destruct
	(
	)
	
	{
		if(is_object($this->PDO) && $this->PDO->inTransaction())
		$this->PDO->rollBack();
	}
	
	public function
	escape
	(
		$string,
		$type='value',
		$wrap=false
	)
	{
		if($type=='object declaration')
		
		{
			$e=explode('.',$string);
			
			$a=array();
			
			foreach($e as $_)
			$a[]=$wrap?'`'.$this->escape($_).'`':$this->escape($_);
			
			return implode('.',$a);
		}
	
		return preg_replace("/^'|'$/",'',$this->quote($string));
	}
	
	public function
	run
	(
		$query,
		array	$arguments=null
	)
	{
		$prepare=$this->prepare($query);
		
		if(!$prepare->execute($arguments))
		throw new Exception('could not execute prepared statement');
		
		return $prepare;
	}
	
	public function
	insert_into
	(
	  $table
	)
	{
	  return new insert_into($table);
	}
	
	public function
	__call
	(
		$function,
		$arguments
	)
	{
		if(method_exists($this->PDO,$function))
		
		{
			try
			{
				return call_user_func_array(array($this->PDO,$function),$arguments);
			}
			catch(\PDOException $e)
			{
				switch($e->errorInfo[0])
				{
					default:
			die(var_dump($e));
						throw new Exception('PDO_ERROR/'.$e->getMessage(),(object)array('PDOException'=>$e));
			
					break;
		
					case 23000:
			
						throw new Exception('PDO_ERROR/SQL_UNIQUE_VIOLATION',(object)array('message'=>$e->errorInfo[2]));
			
					break;
					
					case 42000:
					die(var_dump($e));
						throw new Exception('PDO_ERROR/SYNTAX_ERROR_OR_ACCESS_VIOLATION',(object)array('PDOException'=>$e));
					
					break;
				}
				
				throw new Exception(__FILE__.__LINE__);
			}
		}
		
		return null;
	}
}
